This report presents an analysis of TRO violations (HRS 586-4), Order for Protection violations (HRS 586-11), and harassment by stalking charges (HRS 711-1106.4 and HRS 711-1106.5). The analysis focus on statewide data, disaggregated by circuit [under construction!], over a reporting period between January 1st, 2017 and December 31st, 2025. The following sections contain tables and graphs to explore different aspects of the data.
Code
library(readxl)library(dplyr)library(tidyr)library(DT)df1 <-read_excel("HCR_55_extract_2026-01-15_0954.xlsx")# wrangle data ------------------------------------------------------------## create charge code section categories ----df2 <- df1 %>%mutate(cyear =as.numeric(format(FILING_DATE, "%Y")),charge_code_section =case_when(grepl("586-4", CHARGE_CODE) ~"586-4",grepl("586-11", CHARGE_CODE) ~"586-11",grepl("711-1106.4", CHARGE_CODE) ~"711-1106.4",grepl("711-1106.5", CHARGE_CODE) ~"711-1106.5",.default = CHARGE_CODE ),charge_code_section =factor(charge_code_section, levels =c("586-4", "586-11", "711-1106.4", "711-1106.5"))) #check how many of each offense are charged on each case -> there are indeed cases that have some combo of TRO, OFP, and 711-1106df3_cases_check <- df2 %>%group_by(CASE_ID, PERSON_ID, CHARGE_NUMBER) %>%#if multiple rows for a given charge, select most recent oneslice(1) %>%group_by(CASE_ID, PERSON_ID) %>%summarise(total_charges =n(),TRO_violation =sum(grepl("586-4", charge_code_section)),OFP_violation =sum(grepl("586-11", charge_code_section)),harassment_by_stalking =sum(grepl("711-1106", charge_code_section)) ) %>%ungroup() %>%mutate(combo_case = (TRO_violation >=1) + (OFP_violation >=1) + (harassment_by_stalking >=1) >=2)
Section 1: Cases filed
Out of 6,581 cases filed statewide for TRO violations, OFP violations, or harassment by stalking during the reporting period, 28.7% had more than one charge.
Multiple TRO charges: 10.7%
Multiple OFP charges: 15.9%
Multiple harassment by stalking charges: 0.2%
Combination of TRO violations, OFP violations, and harassment by stalking charges: 1.9%
Because some cases had a combination of TRO violations, OFP violations, and harassment by stalking charges, they are double counted in the case count statistics below.
No cases in this data set had multiple defendants, so the number of cases equals the number of defendants. However, some defendants had multiple cases. An analysis of defendants with multiple cases is provided in section #.
df3_cases <- df2 %>%group_by(CASE_ID, PERSON_ID, charge_code_section) %>%#get one row per charge type per case (allows us to double count when case has more than one charge type)slice(1) %>%ungroup() %>%count(charge_code_section, cyear)### table datadf3_cases_table <- df3_cases %>%pivot_wider(names_from = cyear, values_from = n)datatable(df3_cases_table, options =list(pageLength =10, scrollX =TRUE) )
Code
library(plotly)# Your code to create plot herep1 <-ggplot(df3_cases, aes(y = n, x = cyear, group = charge_code_section, color = charge_code_section,text =paste("Cases filed:", n, "<br>","Charge:", charge_code_section, "<br>","Year:", cyear))) +geom_line() +geom_point() +scale_colour_discrete(limits =c("586-11", "586-4", "711-1106.5", "711-1106.4") # this reorders the legend ) +theme_bw() +theme(axis.text.x =element_text(angle =45, hjust =1)) +labs(x =NULL, # remove "cyear" labely ="Count", # rename "n" to "Count"color ="Charge Code" ) +ggtitle("Frequency of DV case filings between 2017-2025") +NULLplot1 <-ggplotly(p1, tooltip ="text")plot1
Section 2: Charges filed
The data below represents the data at the charge level, To be consistent with case filing data, the year reflects the year the case was initially filed, not when the charge was filed.
At the charge level, cases can have more than one charge both within and across offense categories. The number of charges is necessarily larger than the number of case filings because of this.
library(plotly)p2 <-ggplot(df3_charges, aes(y = n, x = cyear, group = charge_code_section, color = charge_code_section,text =paste("Charges filed:", n, "<br>","Charge:", charge_code_section, "<br>","Year:", cyear) )) +geom_line() +geom_point() +scale_colour_discrete(limits =c("586-11", "586-4", "711-1106.5", "711-1106.4") # this reorders the legend ) +theme_bw() +theme(axis.text.x =element_text(angle =45, hjust =1)) +labs(x =NULL, # remove "cyear" labely ="Count", # rename "n" to "Count"color ="Charge Code" ) +ggtitle("Frequency of DV Charges between 2017-2025") +NULLplot2 <-ggplotly(p2, tooltip ="text")plot2
Section 3: Charge Dispositions
Warning: Disposition estimates are highly unreliable due to inconsistent, inaccurate, and incomplete data entry. These figures may conflict with past and future reports and should be interpreted with significant. The severity of data quality issues makes these statistics unsuitable as a basis for decision-making.
The data below represents the dispositions, if any, on the charges in cases filed during the reporting period. To be consistent with case filing data, the year reflects the year the case was initially filed, not when the charge was disposed.
To view only one charge code section or one disposition category, use the search box. For example, typing “586-11” will show only rows for violation of orders for protection.